package com.t.bricks.bussiness.service.orders.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.t.bricks.bussiness.db.dao.orders.OrdersDao;
import com.t.bricks.bussiness.db.entity.orders.Express;
import com.t.bricks.bussiness.db.entity.orders.Orders;
import com.t.bricks.bussiness.db.entity.orders.base.OrdersBase;
import com.t.bricks.bussiness.model.orders.ConditionOrders;
import com.t.bricks.bussiness.model.orders.OrderDetail;
import com.t.bricks.bussiness.service.orders.OrdersService;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.model.OrderInfoList;
import com.t.bricks.model.Page;
import com.t.bricks.utils.function.data.SequenceUtil;
import com.t.bricks.utils.function.file.ZipUtil;
import com.t.bricks.utils.function.json.JacksonShell;
import com.t.bricks.utils.spring.ModuleUtil;

/**
 * 订单'Orders表'基本业务操作类接口实现
 */
@Service
public class OrdersServiceImpl implements OrdersService {

	@Autowired
	private OrdersDao ordersDao;

	/**
	 * 新增
	 * @param orders 订单 对象实体,注意:跨包访问时可能会是json字符串
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity add(Object orders) {
		MsgEmity me = ModuleUtil.objToEntity(orders, Orders.class);//转换数据,因为如果传递的是String,则可能是进行了跨包访问,要先用Json转换成实体对象
		if (!me.isSuccess()) {
			return me;
		}
		
		Orders ordersData = me.getData();
		
		//--检查订单详情--//
		if (null == ordersData.getOrderDetails() || ordersData.getOrderDetails().size() < 1) {
			return MsgEmity.err(8027, "订单的明细为空");
		}

		double fMoney = 0;
		for (int i = 0; i < ordersData.getOrderDetails().size(); i++) {
			OrderDetail orderDetail = ordersData.getOrderDetails().get(i);
			if (null == orderDetail.getiNumber() || orderDetail.getiNumber() < 1) {
				return MsgEmity.err(8028, "订单中的物品数量不能小于1");
			}
			if (null == orderDetail.getmPrice() || orderDetail.getmPrice().compareTo(BigDecimal.ZERO) == -1) {
				return MsgEmity.err(8029, "订单中的物品售价不能小于0");
			}
			
			fMoney = fMoney + (orderDetail.getmPrice().doubleValue() * 100) * orderDetail.getiNumber();
		}
		
		if (fMoney < 0) {
			return MsgEmity.err(8030, "订单总金额不能小于0");
		}
		
		fMoney = fMoney / 100;
		BigDecimal mMoney = new BigDecimal(String.valueOf(fMoney));//不能直接使用double,否则 123.45会变成123.49999....
		if (null != ordersData.getmMoney()) {
			if (mMoney.compareTo(ordersData.getmMoney()) != 0) {
				return MsgEmity.err(8031, "订单总金额与提交信息不符");
			}
		} else {
			ordersData.setmMoney(mMoney);
		}
		
		//--添加部分缺失的信息--//
		String sOrderId = ModuleUtil.getNewId(10, "Orders");
		
		ordersData.setsId(sOrderId);
		
		if (null == ordersData.getsSequence()) {
			ordersData.setsSequence(SequenceUtil.getSequence());//添加序列号
		}
		
		if (null == ordersData.getdSalesDate()) {
			ordersData.setdSalesDate(new Date());//销售时间
		}

		ordersData.setsSalesmanId(ModuleUtil.currentLoginUserId());//销售员编号
		ordersData.setsSalesman(ModuleUtil.currentLoginUserName());//销售员
		ordersData.setiPay(ordersData.getiPay() == null ? 1 : ordersData.getiPay());//付款方式(0:其它;1:现金;2:支付宝;3微信;4:银行转账;5:赊账:6馈赠)
		
		for (OrderDetail orderDetail : ordersData.getOrderDetails()) {
			orderDetail.setsOrderId(sOrderId);
		}
		
		me = ModuleUtil.validDbEntityByAdd(ordersData);// 通用的基本数据验证,如果要进行比较复杂的数据验证则可以屏蔽掉此方法自行编写
		if (!me.isSuccess()) {
			return me;
		}
		
		me = ModuleUtil.validDbEntityRepeatByAdd((OrdersBase)ordersData, ordersDao);//查询数据库,验证数据是否有重复,因验证数据重复的方式比较复杂,直接在sql脚本中处理
		if (!me.isSuccess()) {// 在false下,如果返回8028则表示数据库查询异常,否则返回后4位是8026的数据,如xxx8026,从万位起表示从数据库中查询的结果
			String tmp = me.getData().toString();
			tmp = tmp.substring(tmp.length() -4, tmp.length());// 数据一定不小于4位
			return me.setData(tmp);// 发现重复数据后不进行其它业务处理则退出时,必须清理返回数据
		}
		
		//ordersData.setsId(null);//清空记录编号
		
		me = ModuleUtil.supplyDbEntityAttrByAdd(ordersData, sOrderId, null);// 补充数据,如添加id、当前用户、当前时间等
		if (!me.isSuccess()) {
			return me;
		}
		
		return ordersDao.add(ordersData);
	}

	/**
	 * 删除
	 * @param iVersion 数据版本号
	 * @param sId 记录编号
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity del(Integer iVersion, String sId) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "信息编号参数错误，请刷新重试！", 8001);
		}
		
		if (null == iVersion || iVersion.intValue() < 1) {
			return new MsgEmity(false, "信息版本参数错误，其值应大于0！", 8002);
		}

		return ordersDao.del(sId, iVersion);
	}

	/**
	 * 根据记录编号取对象
	 * @param sId
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findById(String sId) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "编号不能为空！", 8001);
		}
		
		return ordersDao.findById(sId);
	}
	
	/**
	 * 根据字段名取指定记录编号的数据库表中对应字段的值
	 * @param sId 记录编号
	 * @param fieldNames 待取数据的字段名称集合
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity getValueByFieldName(String sId, List<String> fieldNames) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "编号不能为空！", 8001);
		}
		
		if (null == fieldNames || fieldNames.size() < 1) {
			return new MsgEmity(false, "待查询字段不能为空！", 8002);
		}
		
		return ordersDao.getValueByFieldName(sId, fieldNames);
	}
	
	/**
	 * 根据关键值取对象集合
	 * @param orders 存放查询条件的Orders(订单)对象实体,注意:跨包访问时可能会是json字符串
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findByKey(Object orders) {
		if (null == orders) {
			return new MsgEmity(false, "条件不能为空！", 8000);
		}
		
		MsgEmity me = ModuleUtil.objToEntity(orders, Orders.class);//转换数据,因为如果传递的是String,则可能是进行了跨包访问,要先用Json转换成实体对象
		if (!me.isSuccess()) {
			return me;
		}
		
		Orders ordersData = me.getData();
		
		return ordersDao.findByKey(ordersData);
	}

	/**
	 * 根据关键值查数量
	 * @Param orders 存放查询条件的Orders对象,注意:跨包访问时可能会是json字符串
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findCountByKey(Object orders) {
		if (null == orders) {
			return new MsgEmity(false, "条件对象不能为空！", 8000);
		}
		
		MsgEmity me = ModuleUtil.objToEntity(orders, Orders.class);//转换数据,因为如果传递的是String,则可能是进行了跨包访问,要先用Json转换成实体对象
		if (!me.isSuccess()) {
			return me;
		}
		
		Orders ordersData = me.getData();
		
		return ordersDao.findCountByKey(ordersData);
	}
	
	/**
	 * 查询分页
	 * @param page 分页信息对象
	 * @param orders 排序数据集合
	 * @param sLikeStr 全文检索
	 * @param condition 查询条件对象
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findByPage(Page page, OrderInfoList orders, String sLikeStr,
			ConditionOrders condition) {
		if (null == page) {
			page = new Page(new ArrayList<Orders>());
		}

		return ordersDao.findByPage(page, orders, sLikeStr, condition);
	}

	/**
	 * 根据记录编号查询符合分页数据的某条记录
	 * @param sId
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findByPageRow(String sId) {
		if (null == sId || "".equals(sId.trim())) {
			return new MsgEmity(false, "编号不能为空！", 8001);
		}
		
		return ordersDao.findByPageRow(sId);
	}

	/**
	 * 直接调用数据库操作
	 * @param args 参数集合,注意:参数不要使用基本类型
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity callMapping(Object...args) {
		String funName = ModuleUtil.parentMethodName();//待调用的mybits函数名与controller的接口名必须一致
		if (null == funName || "".equals(funName.trim())) {
			return new MsgEmity(false, "调用方法不明！", 8001);
		}
		
		if (null == args) {
			args = new Object[0];
		}
		
		Class<?>[] argsType = new Class<?>[args.length];
		for (int i = 0; i < args.length; i++) {
			argsType[i] = args[i].getClass();
		}
		
		return ordersDao.callMapping(funName, argsType, args);
	}

	/**
	 * 创建Excel文件内容
	 * @param orders 排序数据集合
	 * @param sLikeStr 全文检索
	 * @param condition 查询条件对象
	 * @return MsgEmity 返回结构中data为创建的经过压缩的Excel内容,接收端需要进行解压,msg为文件名
	 */
	@Override
	public MsgEmity export(OrderInfoList orders, String sLikeStr, ConditionOrders condition) {
		MsgEmity me = ordersDao.findByExport(orders, sLikeStr, condition);//查询数据
		if(!me.isSuccess()) {
			return me;
		}
		
		me = ModuleUtil.crateExcel(me.getData(), "订单.xls");//根据Excel的xml模板创建文件内容
		if(!me.isSuccess()) {
			return me;
		}

		MsgEmity msg = ZipUtil.zipStr(me.getData());//将内容进行压缩,便于传输
		if(!msg.isSuccess()) {
			return msg.setData(100 + (Integer)msg.getData());//提升错误码值
		}
		
		return me.setData(msg.getData());//替换成压缩后的内容
	}

	/**
	 * 修改状态
	 * @param orders
	 * @return MsgEmity 返回执行情况
	 */
	@Override
	public MsgEmity changeState(Orders orders) {
		if (null == orders.getsId() || "".equals(orders.getsId().trim())) {
			return new MsgEmity(false, "编号不能为空！", 8001);
		}
		
		if (null == orders.getiState()) {
			return new MsgEmity(false, "状态值不能为空！", 8002);
		}
		
		if (null == orders.getiVersion() || orders.getiVersion().intValue() < 1) {
			return new MsgEmity(false, "版本号不该小于1！", 8003);
		}
		
		MsgEmity me = ordersDao.changeState(orders);
		if (!me.isSuccess()) {
			return me;
		}
		
		if (orders.getiState() != 4 || null == orders.getExpress()) {
			return me;
		}
		
		Date date = new Date();
		Express express = orders.getExpress();
		express.setsId(orders.getsSequence());
		express.setsDeliverMan(ModuleUtil.currentLoginUserName());
		express.setsCreator(ModuleUtil.currentLoginUserId());
		express.setdCreateDate(date);
		express.setsModifieder(ModuleUtil.currentLoginUserId());
		express.setdModifiedDate(date);
		express.setiState(2);
		express.setiIndex(1);
		express.setiVersion(1);
		
		MsgEmity ma = ModuleUtil.callServiceMethod(
				"expressServiceImpl",
				"add",
				new Class<?>[]{Object.class},
				new Object[]{(Object)(JacksonShell.toJSONString(express))});
		if (!ma.isSuccess()) {
			return MsgEmity.err(8004, "修改订单状态成功,但添加快递单失败");
		}
		
		return me;
	}
	
	//----------------------------- 自动生成代码结束 -----------------------------//

}
